﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace UtopianGame.graphics
{
    public class GraphicalObject
    {
        protected String toolTipText;
        protected Rectangle boundingBox;
        protected Texture2D sprite;
        protected String spriteName;
        protected bool clickable;
        protected ContentManager contentManager;
        protected List<GraphicalObject> subObjectList;
        protected bool isActive;
        protected GraphicalObject parentObj;

        protected int depth;  //depth should not be changed after it is created. It affects where
                            //objects go in the graphicalObjectList.

        //A paramterless constructor is required because of a quirk of C#.
        //Apparently, child classes automatically call the parameterless constructor
        //of their parent when their constructor runs. So this has a parameterless
        //constructor which does nothing, to keep errors from happening.
        //That's really clunky, and I hope to find another solution, but it works for now.
        public GraphicalObject()
        {
        }

        public GraphicalObject(ContentManager cm)
        {
            init(cm);
        }

        protected virtual void init(ContentManager cm)
        {
            toolTipText = "";
            spriteName = "";
            boundingBox = new Rectangle(0, 0, 0, 0);
            subObjectList = new List<GraphicalObject>();
            isActive = true;
            parentObj = null;
            contentManager = cm;
        }

        public Rectangle getBoundingBox()
        {
            return boundingBox;
        }

        public void setBoundingBox(int newX, int newY, int newWidth, int newHeight)
        {
            boundingBox = new Rectangle(newX, newY, newWidth, newHeight);
        }

        public String getToolTipText()
        {
            return toolTipText;
        }

        public void setToolTipText(String newText)
        {
            toolTipText = newText;
        }

        public Texture2D getSprite()
        {
            return sprite;
        }

        public void setSprite(Texture2D newSprite)
        {
            sprite = newSprite;
        }

        public String getSpriteName()
        {
            return spriteName;
        }

        public void setSpriteName(String newName)
        {
            spriteName = newName;
        }

        public void setClickable(bool newClickable)
        {
            clickable = newClickable;
        }

        public bool getClickable()
        {
            return clickable;
        }

        public void setDepth(int newDepth)
        {
            depth = newDepth;
        }

        public int getDepth()
        {
            return depth;
        }

        //Sets the x and y coordinates of the object's bounding box.
        //Returns the new bounding box.
        public Rectangle setCoords(int newX, int newY)
        {
            setBoundingBox(newX, newY, boundingBox.Width, boundingBox.Height);
            return boundingBox;
        }

        public List<GraphicalObject> getSubObjectList()
        {
            return subObjectList;
        }

        public void addToSubObjectList(GraphicalObject newObj, int xCoord = 0, int yCoord = 0, int depth = 0)
        {
            GlobalDataHolder.addGraphicalObject(newObj, xCoord, yCoord, depth);
            subObjectList.Add(newObj);
            newObj.setParentObject(this);
        }

        //NOTE: This function should rarely be used.
        //It removes something from the subObjectList, but not the
        //graphicalObjectList, and doesn't make it inactive.
        public void removeFromSubObjectList(GraphicalObject objToRemove)
        {
            subObjectList.Remove(objToRemove);
        }

        public void setIsActive(bool newActive)
        {
            isActive = newActive;
        }

        public bool getIsActive()
        {
            return isActive;
        }

        public void setParentObject(GraphicalObject newObj)
        {
            parentObj = newObj;
        }

        public GraphicalObject getParentObject()
        {
            return parentObj;
        }

        //This function displays the sprite of this GraphicalObject.
        public virtual void draw(SpriteBatch sb)
        {
            sb.Draw(sprite, boundingBox, Color.White);
        }

        //This function should be overridden if a child class has certain
        //behavior upon being clicked.
        public virtual void clicked(MouseState m)
        {
        }


        //Called when a graphicalObject is removed from the graphicalObjectList.
        public virtual void removed()
        {
        }
    }
}
